


#include "qelib.h"
#include "ps_uart.h"



#define XUARTPS_SR_TNFUL	0x00004000U /**< TX FIFO Nearly Full Status */
#define XUARTPS_SR_TTRIG	0x00002000U /**< TX FIFO Trigger Status */
#define XUARTPS_SR_FLOWDEL	0x00001000U /**< RX FIFO fill over flow delay */
#define XUARTPS_SR_TACTIVE	0x00000800U /**< TX active */
#define XUARTPS_SR_RACTIVE	0x00000400U /**< RX active */
#define XUARTPS_SR_TXFULL	0x00000010U /**< TX FIFO full */
#define XUARTPS_SR_TXEMPTY	0x00000008U /**< TX FIFO empty */
#define XUARTPS_SR_RXFULL	0x00000004U /**< RX FIFO full */
#define XUARTPS_SR_RXEMPTY	0x00000002U /**< RX FIFO empty */
#define XUARTPS_SR_RXOVR	0x00000001U /**< RX FIFO fill over trigger */

struct ps_uart_regs {
    qe_u32 cr;              /* 0x0000U Control Register */
    qe_u32 mr;              /* 0x0004U Mode Register */
    qe_u32 ier;             /* 0x0008U Interrupt Enable */
    qe_u32 idr;             /* 0x000CU Interrupt Disable */
    qe_u32 imr;             /* 0x0010U Interrupt Mask */
    qe_u32 isr;             /* 0x0014U Interrupt Status */
    qe_u32 buadrate_gen;    /* 0x0018U Baud Rate Generator */
    qe_u32 rxt;             /* 0x001CU RX Timeout */
    qe_u32 rxwm;            /* 0x0020U RX FIFO Trigger Level */
    qe_u32 mdm_cr;          /* 0x0024U Modem Control */
    qe_u32 mdm_sr;          /* 0x0028U Modem Status */
    qe_u32 sr;              /* 0x002CU Channel Status */
    qe_u32 fifo;            /* 0x0030U FIFO */
    qe_u32 buadrate_div;    /* 0x0034U Baud Rate Divider */
    qe_u32 flow_delay;      /* 0x0038U Flow Delay */
    qe_u32 reserved1;
    qe_u32 reserved2;
    qe_u32 txwm;            /* 0x0044U TX FIFO Trigger Level */
    qe_u32 rxbs;            /* 0x0048U RX FIFO Byte Status */
};

static qe_bool ps_uart_is_transmit_full(struct ps_uart_regs *regs)
{
    return (regs->sr & XUARTPS_SR_TXFULL);
}

void ps_uart_out(qe_u32 *base, qe_u8 data)
{
    struct ps_uart_regs *regs = (struct ps_uart_regs *)base;
	/* Wait until there is space in TX FIFO */
	while (ps_uart_is_transmit_full(regs)) {
		;
	}

	/* Write the byte into the TX FIFO */
    regs->fifo = data;
}